﻿using System;
using System.Collections.Generic;
using System.Linq;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace M.Comunicate
{
    public class sPort
    {
        //信息委托
        public delegate void TcpCommunicationData(string value);
        public event TcpCommunicationData CommunicationTexts;

        public delegate void TcpCommunicationData_buff(byte[] value);
        public event TcpCommunicationData_buff CommunicationTexts_buff;

        public SerialPort serialPort = new SerialPort();
        /// <summary>
        /// 自动获取串口的端口号
        /// </summary>
        /// <returns></returns>
        public DataTable GetComList(DataTable Port_DataTable)
        {
            Port_DataTable.Columns.Add("PortName", typeof(string));

            string[] names = SerialPort.GetPortNames();
            Port_DataTable.Clear();

            for (int i = 0; i < names.Length; i++)
            {
                DataRow dr = Port_DataTable.NewRow();
                dr["PortName"] = names[i];
                Port_DataTable.Rows.Add(dr);
            }
            return Port_DataTable;
        }

        /// <summary>
        /// 判断DataTable中  是否存在该数据
        /// </summary>
        /// <param name="Port_DataTable"></param>
        /// <param name="name"></param>
        /// <returns>true 为存在   false 为不存在</returns>
        public bool ifDataTable_exist(DataTable Port_DataTable, string name)
        {
            bool ifData = false;
            foreach (DataRow dr in Port_DataTable.Rows)
            {
                if (dr["PortName"].ToString() == name)
                {
                    ifData = true;
                }
            }
            return ifData;
        }

        /// <summary>
        /// 判断串口是否打开
        /// </summary>
        /// <param name="serialPort"></param>
        /// <returns></returns>
        public bool IfProtNoAndOff()
        {
            return serialPort.IsOpen;
        }

        /// <summary>
        /// 打开串口
        /// </summary>
        /// <param name="serialPort"></param>
        /// <param name="name"></param>
        /// <returns>成功返回true</returns>
        public bool opencom(string name, int Baud, Parity parO = System.IO.Ports.Parity.None)
        {
            try
            {
                //波特率
                serialPort.BaudRate = Baud;
                //数据位
                serialPort.DataBits = 8;
                serialPort.PortName = name;
                //1个停止位
                serialPort.StopBits = System.IO.Ports.StopBits.One;
                //无奇偶校验位
                serialPort.Parity = parO;
                serialPort.ReadTimeout = 100;
                serialPort.Open();
                if (!serialPort.IsOpen)
                {
                    Console.WriteLine("端口打开失败");
                    return false;
                }
                else
                {
                    serialPort.DataReceived += serialPort_DataReceived;
                    return true;
                }

            }
            catch (Exception ex)
            {
                serialPort.Dispose();
                return false;
            }
        }

        /// <summary>
        /// 串口发送
        /// </summary>
        /// <param name="Data">数据</param>
        public bool SendPort_Hex(string Data)
        {
            // 向串口写数据，并返回是否写入成功的结果
            try
            {
                if (serialPort.IsOpen)
                {
                    string[] hexValuesSplit = Data.Split(' ');
                    byte[] bytes = new byte[hexValuesSplit.Length];
                    for (int i = 0; i < hexValuesSplit.Length; i++)
                    {
                        bytes[i] = Convert.ToByte(hexValuesSplit[i], 16);
                    }
                    serialPort.Write(bytes, 0, bytes.Length);
                    Thread.Sleep(10);
                    return true;
                }
                else
                {
                    //串口未打开
                    return false;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message); // 输出错误信息
                return false;
            }

        }

        /// <summary>
        /// 串口发送
        /// </summary>
        /// <param name="Data">数据</param>
        public bool SendPort(string Data)
        {
            // 向串口写数据，并返回是否写入成功的结果
            try
            {
                if (serialPort.IsOpen)
                {
                    serialPort.Write(Data);
                    Thread.Sleep(10);
                    return true;
                }
                else
                {
                    //串口未打开
                    return false;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message); // 输出错误信息
                return false;
            }

        }


        /// <summary>
        /// 接受串口数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            ((SerialPort)sender).PortName.ToString();
            Thread.Sleep(50);  //（毫秒）等待一定时间，确保数据的完整性 int len        
            int len = serialPort.BytesToRead;
            string receivedata = string.Empty;
            if (len != 0)
            {
                byte[] buff = new byte[len];
                serialPort.Read(buff, 0, len);
                receivedata = Encoding.Default.GetString(buff);

                CommunicationTexts?.Invoke(receivedata);
                CommunicationTexts_buff?.Invoke(buff);


            }
            //richTextBox1.AppendText(receivedata + "\r\n");
        }

        /// <summary>
        /// 断开串口
        /// </summary>
        /// <param name="serialPort"></param>
        public void Port_Disconnect()
        {
            // 关闭串口，并返回是否关闭成功的结果
            try
            {
                if (serialPort.IsOpen) // 如果串口已打开
                {
                    serialPort.Close(); // 关闭串口
                    serialPort.Dispose();
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message); // 输出错误信息
            }
        }

    }
}
